package com.rf.richfitwheel.admin.sys.controller;

import com.rf.richfitwheel.admin.annotation.UserOperateLog;
import com.rf.richfitwheel.admin.contants.UrlConstant;
import com.rf.richfitwheel.admin.sys.model.MenuBean;
import com.rf.richfitwheel.admin.sys.model.OrgVO;
import com.rf.richfitwheel.admin.sys.model.UserRole;
import com.rf.richfitwheel.admin.sys.service.*;
import com.rf.richfitwheel.admin.sys.vo.UserVO;
import com.rf.richfitwheel.admin.utils.UserUtil;
import com.rf.richfitwheel.common.contants.Constant;
import com.rf.richfitwheel.common.exception.BusinessException;
import com.rf.richfitwheel.common.utils.R;
import com.rf.richfitwheel.common.utils.TreeUtils;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import org.apache.commons.lang.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 权限相关
 *
 * @author hushouquan
 */
@RestController
@RequestMapping(UrlConstant.WEB_ADMIN_URL + "/userAuth")
public class SysUserAuthController {

    private static Logger log = LoggerFactory.getLogger(SysUserAuthController.class);

    @Autowired
    private SysMenuService sysMenuService;

    @Autowired
    private OrgService orgService;

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private SysUserAuthService sysUserAuthService;

    @Autowired
    private SysUserAuthDataService sysUserAuthDataService;
    @Autowired
    private SysUserRoleService sysUserRoleService;

    /**
     * 导航菜单，根据终端组织的菜单
     *
     * @param terminal 必须传入，可参考 {@link com.rf.richfitwheel.common.contants.Constant.TerminalType}
     * @return
     */
    @GetMapping("/navByTerminal/{terminal}")
    public R navByTerminal(@PathVariable("terminal") String terminal, HttpServletRequest request) {
        UserVO userVO = UserUtil.getUser();
        String sessionId = request.getRequestedSessionId();
        String moduleType = request.getHeader("moduleType") == null ? request.getHeader("Moduletype") : request.getHeader("moduleType"); //从请求头获取模块类型，如果有值就查对应模块菜单
        try {
            List<MenuBean> menuList = new ArrayList<>();
            if(StringUtils.isNotBlank(moduleType)){
                menuList = sysMenuService.getUserMenuList(userVO.getId(), terminal, moduleType, sessionId);
            }else{
                menuList = sysMenuService.getUserMenuList(userVO.getId(), terminal, sessionId);
            }
            // 查询按钮权限列表
            Set<String> permissions = sysMenuService.getUserPermissions(userVO.getId(), terminal);
            
            List<Map<String, Object>> modules = userVO.getDefaultOrg() == null ? new ArrayList<>() : sysMenuService.getUserModulesPermissions(userVO);
            return R.ok().put("menuList", menuList).put("permissions", permissions).put("modules", modules);
        } catch (BusinessException e) {
            return R.error(e.getMessage());
        } catch (Exception e) {
            log.error("根据终端组织的菜单失败", e);
            return R.error("根据终端组织的菜单失败");
        }

    }

    /**
     * 导航菜单，根据终和模块端组织的菜单
     * @param terminal 终端类型 {@Link com.rf.richfitwheel.common.contants.Constant.TerminalType}
     * @param module 模块 {@Link com.rf.richfitwheel.common.contants.Constant.SystemModule}
     * @param request 会话
     * @return {code:'',msg:'',menuList:[],permissions:[],modules:[]}
     */
    @GetMapping("/navByTerminal/{terminal}/{module}")
    public R navByTerminal(@PathVariable("terminal") String terminal, @PathVariable("module") String module, HttpServletRequest request) {
        UserVO userVO = UserUtil.getUser();
        String sessionId = request.getRequestedSessionId();
//        request.getHeader("moduleType");
        try {
//			String[]  terminals = getTerminals(terminal, request);
            List<MenuBean> menuList = sysMenuService.getUserMenuList(userVO.getId(), terminal, module, sessionId);
            // 查询按钮权限列表
            Set<String> permissions = sysMenuService.getUserPermissions(userVO.getId(), terminal);
            List<Map<String, Object>> modules = userVO.getDefaultOrg() == null ? new ArrayList<>() : sysMenuService.getUserModulesPermissions(userVO);
            return R.ok().put("menuList", menuList).put("permissions", permissions).put("modules", modules);
        } catch (BusinessException e) {
            return R.error(e.getMessage());
        } catch (Exception e) {
            log.error("根据终端组织的菜单失败", e);
            return R.error("根据终端组织的菜单失败");
        }

    }


    /**
     * 导航菜单，根据终端组织的菜单
     *
     * @param terminal 必须传入，可参考 {@link com.rf.richfitwheel.common.contants.Constant.TerminalType}
     * @return
     */
    @GetMapping("/allNavByTerminal/{terminal}")
    public R allNavByTerminal(@PathVariable("terminal") String terminal, HttpServletRequest request) {
        UserVO userVO = UserUtil.getUser();
        String sessionId = request.getRequestedSessionId();
        try {
//			String[]  terminals = getTerminals(terminal, request);
            List<MenuBean> menuList = sysMenuService.getUserAllMenuList(userVO.getId(), terminal, sessionId);
            // 查询按钮权限列表
            Set<String> permissions = sysMenuService.getUserPermissions(userVO.getId(), terminal);
            return R.ok().put("menuList", menuList).put("permissions", permissions);
        } catch (BusinessException e) {
            return R.error(e.getMessage());
        } catch (Exception e) {
            log.error("根据终端组织的菜单失败", e);
            return R.error("根据终端组织的菜单失败");
        }

    }

    /**
     * 获取登录的用户信息
     */
    @GetMapping("/info/{orgId}")
    public R info(@PathVariable("orgId") String orgId) {
        UserVO userVO = UserUtil.getUser();
        Map<String, String> map = new HashMap<>();
        map.put("userId", userVO.getId());
        if (StringUtils.isNotEmpty(orgId) && !orgId.equals("null")) {
            OrgVO orgVO = orgService.getOrgAndParentOrgByOrgId(orgId);
            Map<String, String> dataLevels = sysUserAuthDataService.getAuthDataByUserIdAndOrgId(userVO.getId(), orgVO.getId());
            orgVO.setDataLevels(dataLevels);
            //管辖部门对应模块的数据权限,key是模块，value是数据权限
            userVO.setDefaultOrg(orgVO);
            if(Constant.OrgRank.ORGRANK_DEPT.getValue().equals(orgVO.getOrgRank())){
                userVO.setDefaultDeptId(orgVO.getId());
                userVO.setDefaultDeptCode(orgVO.getOrgCode());
                userVO.setDefaultDeptName(orgVO.getOrgName());
                userVO.setDefaultOrgId(null);
                userVO.setDefaultOrgCode(null);
                userVO.setDefaultOrgName(null);
            }else{
                userVO.setDefaultDeptId(null);
                userVO.setDefaultDeptCode(null);
                userVO.setDefaultDeptName(null);
                userVO.setDefaultOrgId(orgVO.getId());
                userVO.setDefaultOrgCode(orgVO.getOrgCode());
                userVO.setDefaultOrgName(orgVO.getOrgName());
            }
            /*userVO.setDefaultDeptId(orgVO.getId());
            userVO.setDefaultDeptCode(orgVO.getOrgCode());
            userVO.setDefaultDeptName(orgVO.getOrgName());
            userVO.setDefaultOrgId(orgVO.getParentOrg() == null ? null : orgVO.getParentOrg().getId());
            userVO.setDefaultOrgCode(orgVO.getParentOrg() == null ? null : orgVO.getParentOrg().getOrgCode());
            userVO.setDefaultOrgName(orgVO.getParentOrg() == null ? null : orgVO.getParentOrg().getOrgName());*/
            List<String> roles = sysUserRoleService.getListByUserId(userVO.getId())
                    .stream().map(UserRole::getRoleId).collect(Collectors.toList());
            userVO.setRoles(roles);
            UserUtil.setUser(userVO);
        }
        List<Map<String, Object>> modules = sysMenuService.getUserModulesPermissions(userVO);
        return R.ok().put("user", userVO).put("modules", modules);
    }

    /**
     * @param orgVO
     * @功能描述: 切换机构时，将选择的机构更换usevo中的信息，并返给前端
     * @auther: jiaozhongcai
     * @date: 2021/7/7 15:38
     * @return: R
     */
    @PostMapping("/changeOrg")
    public R changeOrg(@RequestBody OrgVO orgVO) {
        //取出session中的uservo，存放当前用户选择切换的机构信息
        UserVO userVO = UserUtil.getUser();
        if (StringUtils.isNotEmpty(orgVO.getId())) {
            OrgVO orgVO1 = orgService.getOrgAndParentOrgByOrgId(orgVO.getId());
            //管辖部门对应模块的数据权限,key是模块，value是数据权限
            Map<String, String> dataLevels = sysUserAuthDataService.getAuthDataByUserIdAndOrgId(userVO.getId(), orgVO.getId());
            orgVO1.setDataLevels(dataLevels);
            userVO.setDefaultOrg(orgVO1);
            if(Constant.OrgRank.ORGRANK_DEPT.getValue().equals(orgVO1.getOrgRank())){
                userVO.setDefaultDeptId(orgVO1.getId());
                userVO.setDefaultDeptCode(orgVO1.getOrgCode());
                userVO.setDefaultDeptName(orgVO1.getOrgName());
                userVO.setDefaultOrgId(null);
                userVO.setDefaultOrgCode(null);
                userVO.setDefaultOrgName(null);
            }else{
                userVO.setDefaultDeptId(null);
                userVO.setDefaultDeptCode(null);
                userVO.setDefaultDeptName(null);
                userVO.setDefaultOrgId(orgVO1.getId());
                userVO.setDefaultOrgCode(orgVO1.getOrgCode());
                userVO.setDefaultOrgName(orgVO1.getOrgName());
            }
        }
        //更新缓存
        UserUtil.setUser(userVO);
        List<Map<String, Object>> modules = sysMenuService.getUserModulesPermissions(userVO);
        return R.ok().put("user", userVO).put("modules", modules);
    }


    /**
     * 导航菜单,常用菜单选择树
     *
     * @param
     * @return
     */
    @GetMapping("/getCommUseMenuSetTree/{terminal}")
    public R getCommUseMenuSetTree() {
        UserVO userVO = UserUtil.getUser();
        try {
            List<Map<String, Object>> menuList = sysMenuService.getCommUseMenuSetTree(userVO.getId(), Constant.TerminalType.TERMINALTYPE_PC.getValue());
            List<TreeUtils> listTree = TreeUtils.getTreeListMap(menuList, "id", "parent_id", "name", "disabled", null);
            List<MenuBean> menucheckList = sysMenuService.getMenuCheckList(userVO.getId(), Constant.TerminalType.TERMINALTYPE_PC.getValue());
            return R.ok().put("menuList", listTree).put("menucheckList", menucheckList);
        } catch (Exception e) {
            return R.error(998, "查询数据失败");
        }
    }

    /**
     * 设置常用菜单
     *
     * @param obj
     * @return
     */
    @UserOperateLog(module = "系统功能", methods = "saveCommUseMenu", description = "设置常用菜单")
    @PostMapping("/saveCommUseMenu")
    public R saveCommUseMenu(@RequestBody JSONObject obj) {
        try {
            UserVO userVO = UserUtil.getUser();
            JSONArray array = JSONArray.fromObject(obj.get("ids"));
            String[] ids = new String[array.size()];
            for (int i = 0; i < array.size(); i++) {
                ids[i] = array.getString(i);
            }
            sysMenuService.saveCommUseMenu(ids, userVO);
            return R.ok();
        } catch (Exception e) {
            log.error("保存常用功能失败", e);
            return R.error(998, "保存失败" + e.getMessage());
        }
    }

    /**
     * 导航菜单,常用菜单
     */
    @GetMapping("/getCommUseMenuTreeByTerminal/{terminal}")
    public R getCommUseMenuTreeByTerminal(@PathVariable("terminal") String terminal, HttpServletRequest request) {
        UserVO userVO = UserUtil.getUser();
        try {
            String[] terminals = {terminal};
            List<MenuBean> menuList = sysMenuService.getCommUseMenuTreeByTerminal(userVO.getId(), terminals);
            return R.ok().put("commUseMenu", menuList);
        } catch (BusinessException e) {
            return R.error(e.getMessage());
        } catch (Exception e) {
            log.error("根据终端组织的菜单失败", e);
            return R.error("根据终端组织的菜单失败");
        }
    }

    @GetMapping("/getUserInfo")
    public R getUserInfo() {
        UserVO userVO = UserUtil.getUser();
        return R.ok().put("userVO", userVO);
    }
}
